package epoch.game.core.distr.service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import epoch.game.core.distr.annotation.ServiceImpl;
import epoch.game.core.distr.config.NodeConfig;

/**
 * 服务定位器
 * @author will
 * @date 2016年4月5日 下午4:32:38
 */
public class ServiceLocator {
	
	// 服务类名称与id映射关系
	public static Map<Class<?>,Integer> serviceIdMap = new ConcurrentHashMap<>();
	//服务和节点映射关系<serverId, nodeId>
	public static Map<Integer,Integer> serviceNodeMap = new HashMap<>();
	//本节点所有的服务
	public static Map<Integer, IService> localServices = new ConcurrentHashMap<>();
	public static Map<Class<?>, IService> nodeServices = new ConcurrentHashMap<>();
	
	/**
	 * 注册服务类和服务id所在的node
	 * @param clasz 服务接口
	 * @param serviceId 服务id
	 * @param nodeId 服务节点id
	 */
	public static void register(Class<?> clasz, int serviceId, int nodeId){
		serviceIdMap.put(clasz, serviceId);
		serviceNodeMap.put(serviceId,nodeId);
	}
	
	public static void setServiceNodeId(int serviceId, int nodeId){
		serviceNodeMap.put(serviceId,nodeId);
	}
	
	/**
	 * 注册本节点的服务
	 * @param service
	 */
	public static void register(int serviceId, IService service){
		Class<? extends IService> servClass = service.getClass();
		ServiceImpl anno = servClass.getAnnotation(ServiceImpl.class);
		Class<?> sclass = anno.value();
		localServices.put(serviceId, service);
		nodeServices.put(sclass, service);
	}
	
	/**
	 * 根据服务接口获取服务id
	 * @param clasz
	 * @return
	 */
	public static int getServiceId(Class<?> clasz) {
		if(!clasz.isInterface()){
			ServiceImpl anno = clasz.getAnnotation(ServiceImpl.class);
			clasz = anno.value();
		}
		int serviceId = 0;
		if (serviceIdMap.containsKey(clasz)) {
			serviceId = serviceIdMap.get(clasz);
		}
		return serviceId;
	}

	/**
	 * 根据服务接口获取服务所在的服务节点id
	 * @param clasz
	 * @return
	 */
	public static int getServiceNodeId(Class<?> clasz) {
		Integer serviceId = serviceIdMap.get(clasz);
		if (serviceId != null) {
			Integer nodeId = serviceNodeMap.get(serviceId);
			if(nodeId!=null){
				return nodeId;
			}			
		}
		return 0;
	}
	
	/**
	 * 根据服务Id获取服务所在的服务节点id
	 * @param clasz
	 * @return
	 */
	public static int getServiceNodeId(int serviceId) {
		Integer nodeId = serviceNodeMap.get(serviceId);
		if(nodeId!=null){
			return nodeId;
		}
		return 0;
	}
	public static int getServiceNodeId(int serverId, int serviceId) {
		int nodeId = getServiceNodeId(serviceId);
		return NodeConfig.nodeId(serverId, NodeConfig.nId(nodeId));
	}
	
	/**
	 * 根据服务名称获取服务所在的服务节点id
	 * @param clasz
	 * @return
	 */
	public static int getServiceNodeId(String serviceName) {
		List<Integer> nodes = NodeConfig.servToNode.get(serviceName);
		if(nodes==null||nodes.isEmpty()){
			return 0;
		}
		return nodes.get(0);
	}
	
	/**
	 * 根据服务接口获取本节点的服务实例
	 * @param serviceClass
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static <S> S getService(int serviceId){
		if(!localServices.containsKey(serviceId)){
			return null;
		}
		return (S)localServices.get(serviceId);
	}
	
	/**
	 * 根据服务接口获取本节点的服务实例
	 * @param serviceClass
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static <S> S getService(Class<?> serviceClass){
		if(!nodeServices.containsKey(serviceClass)){
			return null;
		}
		return (S)nodeServices.get(serviceClass);
	}
}
